home *** CD-ROM | disk | FTP | other *** search
- // Mouse class: msmouse.cpp
-
- #include "dos.h"
- #include "stdlib.h"
- #include "msmouse.h"
-
- const int MsCall = 0x33;
- const int Iret = 0xcf;
- const int False = 0;
- const int True = 1;
-
- MouseObject Mouse;
-
- MouseObject::MouseObject(void)
- // Initializes mouse to a known state. Mouse is not turned on yet
- {
- OK = False;
- MouseOff = True;
- }
-
- int MouseObject::DriverExists(void)
- // Returns true if a mouse driver is installed. This function makes
- // sure the interrupt vector location serviced by the mouse is
- // pointing to something--hopefully the mouse driver.
- {
- void far *address;
- // Look for NULL address or IRET instruction
- address = getvect(0x33);
- return (address != NULL) && (*(unsigned char far *)address != Iret);
- }
-
- void MouseObject::Setup(VideoModeType VideoMode)
- // Initializes the mouse object by verifying that the mouse driver
- // exists, that the mouse responds to its initialization function,
- // by moving the mouse to the top left of the screen, and by setting
- // various internal variables. Call the method SetupOK after
- // calling Init to find out if the mouse initialization was successful.
- // The VideoMode parameter specifies which video mode the mouse is
- // being used under.
- {
- REGS regs;
-
- OK = DriverExists();
- if (OK) { // Mouse present, but will it reset?
- regs.x.ax = 0;
- int86(MsCall, ®s, ®s);
- if (regs.x.ax == 0) OK = False;
- }
- if (!OK) { // Mouse initialization failed. Set
- TurnOff(); // the mouse state off and return.
- return;
- }
- TurnOn(); // Set the mouse state on
-
- if (VideoMode == TextScrn) TextMode = True; else TextMode = False;
- if (VideoMode == LowResGr) LowRes = True; else LowRes = False;
- // Fix up hercules mode for page 0. Use 5 for page 1.
- if (VideoMode == HerculesGr) *(char far *)MK_FP(0x0040,0x0049) = 6;
-
- OldX = 0; OldY = 0; // Initialize various instance variables
- X = 0; Y = 0;
- Dx = 0; Dy = 0;
- Move(0,0); // Set the mouse to top,left of screen
- }
-
- int MouseObject::SetupOK(void)
- // Returns true only if the mouse initialization was successful
- {
- return OK;
- }
-
- void MouseObject::Hide(void)
- // Hides the mouse cursor. Call this function to remove the mouse
- // cursor from the screen.
- {
- REGS regs;
- if (!Operating()) return;
- regs.x.ax = 2;
- int86(MsCall, ®s, ®s);
- }
-
- void MouseObject::Show(void)
- // Displays the mouse cursor
- {
- REGS regs;
- if (!Operating()) return;
- regs.x.ax = 1;
- int86(MsCall, ®s, ®s);
- }
-
- unsigned MouseObject::Status(int &Mx, int &My)
- // This general function returns the location of the mouse in Mx,My
- // and the current status of the buttons in the function name
- {
- REGS regs;
-
- if (!Operating()) { Mx = 0; My = 0; return 0; }
- regs.x.ax = 3;
- int86(MsCall, ®s, ®s);
- Mx = regs.x.cx; My = regs.x.dx;
- if (TextMode) {
- Mx >>= 3; // Adjust for text coordinates
- My >>= 3;
- }
- if (LowRes) Mx >>= 1; // Adjust for 320x200 coordinates
- return regs.x.bx;
- }
-
- unsigned MouseObject::ButtonStatus(void)
- // Returns the status of the mouse buttons
- {
- int Mx, My;
- if (!Operating()) return 0; else return Status(Mx, My);
- }
-
- int MouseObject::PressCnt(unsigned ButtonMask)
- // Returns number of times the button has been pressed since
- // last time called
- {
- REGS regs;
- if (!Operating()) return 0;
- regs.x.ax = 5;
- regs.x.bx = ButtonMask >> 1; // Button selector
- int86(MsCall, ®s, ®s);
- return regs.x.bx;
- }
-
- int MouseObject::ReleaseCnt(unsigned ButtonMask)
- // Returns number of times the button has been released since
- // last time called
- {
- REGS regs;
- if (!Operating()) return 0;
- regs.x.ax = 6;
- regs.x.bx = ButtonMask >> 1; // Button selector
- int86(MsCall, ®s, ®s);
- return regs.x.bx;
- }
-
- unsigned MouseObject::Event(int &Mx, int &My)
- // Gets the last mouse event. The left mouse button has priority
- // over the right button.
- {
- unsigned E;
-
- if (!Operating()) { Mx = 0; My = 0; return Idle; }
- // Get current status of buttons.
- E = Status(Mx,My);
- if (E == 0) {
- // No mouse button down, but maybe there was a button press that
- // was missed. If not, check to see whether a button release was
- // missed. Favor the left mouse button.
- if (PressCnt(LeftButton) > 0) E = LMouseDown;
- else if (PressCnt(RightButton) > 0) E = RMouseDown;
- // Maybe left one was just released
- else if (ReleaseCnt(LeftButton) > 0) E = LMouseUp;
- // Maybe right one was just released
- else if (ReleaseCnt(RightButton) > 0) E = RMouseUp;
- }
- else { // A mouse button is down
- // Was the left button already down?
- if (E & LeftButton) {
- // Not already down
- if (PressCnt(LeftButton) > 0)
- E = LMouseDown; // Must have just been pressed
- else E = LMouseStillDown; // Already down
- }
- else if (PressCnt(RightButton) > 0)
- E = RMouseDown; // Must have just been pressed
- else E = RMouseStillDown; // Already down
- }
- return E; // Return the mouse event code
- }
-
- unsigned MouseObject::WaitForAnyEvent(int &Mx, int &My)
- // Waits for a mouse event to occur and return its code
- {
- unsigned E;
-
- if (!Operating()) { Mx = 0; My = 0; return Idle; }
- do {
- E = Event(Mx, My);
- } while (E == Idle);
- return E;
- }
-
- void MouseObject::WaitForEvent(unsigned E, int &Mx, int &My)
- // Waits for the event E to occur. Return its mouse coordinates.
- {
- unsigned Etry;
- if (!Operating()) { Mx = 0; My = 0; return; }
- do {
- Etry = Event(Mx, My);
- } while (Etry != E);
- }
-
- int MouseObject::Moved(void)
- // Tests to see if the mouse has moved since the last time this
- // method was called.
- {
- if (!Operating()) return False;
- OldX = X; OldY = Y;
- Status(X, Y);
- Dx = X - OldX; Dy = Y - OldY;
- return (Dx != 0) || (Dy != 0);
- }
-
- void MouseObject::Move(int Mx, int My)
- // Moves the mouse cursor
- {
- REGS regs;
-
- if (!Operating()) return;
- regs.x.ax = 4;
- regs.x.cx = Mx;
- regs.x.dx = My;
- if (TextMode) { // Adjust for text coordinates
- regs.x.cx <<= 3;
- regs.x.dx <<= 3;
- }
- if (LowRes) regs.x.cx <<= 1; // Adjust for 320x200 coordinates
- int86(MsCall, ®s, ®s);
- }
-
- void MouseObject::TurnOn(void)
- // Enables the mouse code
- {
- if (OK && MouseOff) {
- MouseOff = False;
- Show();
- }
- }
-
- void MouseObject::TurnOff(void)
- // Disables the mouse code. This is useful when you don't want to
- // use the mouse, but the code already has mouse calls in it.
- {
- if (OK && !MouseOff) {
- Hide();
- MouseOff = True;
- }
- }
-
- int MouseObject::Operating(void)
- // Returns a boolean flag that is true only if the mouse
- // object has been enabled. This is the default state.
- {
- return !MouseOff;
- }
-
- void MouseObject::SetGCursor(const MouseCursor &NewCursor)
- // Sets the graphics mouse cursor to the type specified
- {
- REGS regs;
- SREGS sregs;
-
- if (!Operating()) return;
- regs.x.ax = 9;
- regs.x.bx = NewCursor.HotSpot.X;
- regs.x.cx = NewCursor.HotSpot.Y;
- regs.x.dx = FP_OFF(NewCursor.ScreenMask);
- sregs.es = FP_SEG(NewCursor.ScreenMask);
- int86x(MsCall, ®s, ®s, &sregs);
- }
-
-